package bll

import (
	"context"
	"golang.org/x/sync/errgroup"
	"manager/auth"
	log "manager/collector/logger"
	"manager/store/postgres"
	"manager/utils"
	"time"

	"manager/event"
	"manager/model"
	"manager/model/entity"
	"manager/store"
)

type userEbike struct {
	iUserEbike store.IUserEbike
}

var UserEbike = &userEbike{}

func (a *userEbike) init() func() {
	a.iUserEbike = postgres.UserEbike
	return func() {}
}

func (a *userEbike) onEvent(data *event.Data) {
	if data == nil || (data.Type != event.Event_UnBind_Bike) {
		return
	}

	log.Info("---------------- userEbike onEvent data:", utils.ToJsonString(data))
	if event.Event_UnBind_Bike == data.Type {
		// 解析参数
		obj := data.Data.(*event.UnBindBike)
		if obj == nil {
			log.Error("shareEbike onEvent err")
			return
		}

		// 参数校验
		if obj.BikeId == 0 || obj.UserId == 0 {
			log.Errorf("shareEbike onEvent params error userId:%v bikeId:%v", obj.UserId, obj.BikeId)
			return
		}

		// 查询用户电车信息
		/*	info, _ := a.iUserEbike.FindByParameter(context.Background(), &model.UserEbikeRequest{
				UserID:  &obj.UserId,
				EbikeID: &obj.BikeId,
			})
			if info.ID == 0 {
				return
			}

			// 删除用户电车信息
			a.iUserEbike.Delete(context.Background(), info.ID)*/
	}
}

func (a *userEbike) Create(ctx context.Context, in *model.UserEbikeCreateRequest) error {
	var (
		err error
	)

	c := buildUserEbike(in)
	_, err = a.iUserEbike.Create(ctx, c)
	return err
}

func (a *userEbike) Update(ctx context.Context, in *model.UserEbikeUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)
	if in.UserID != nil {
		dict["user_id"] = in.UserID
	}
	if in.EbikeID != nil {
		dict["ebike_id"] = in.EbikeID
	}
	if in.ShareTime != nil {
		dict["share_time"] = in.ShareTime
	}

	if in.IsManager != nil {
		dict["is_manager"] = in.IsManager
	}

	dict["updated_at"] = time.Now().Unix()

	// do other update here

	return a.iUserEbike.Update(ctx, in.ID, dict)
}

func (a *userEbike) Delete(ctx context.Context, in *model.UserEbikeDeleteRequest) error {
	return a.iUserEbike.Delete(ctx, in.ID)
}

// FindCountByIds 用户ID 查询车辆数量
func (a *userEbike) FindCountByIds(ctx context.Context, ids []int64) ([]*model.FindCountByIdsResponse, error) {
	var (
		err error
	)
	out, err := a.iUserEbike.FindCountByIds(ctx, ids)
	if err != nil {
		return nil, err
	}

	return out, err
}

// Detail 用户车辆详情
func (a *userEbike) Detail(ctx context.Context, in *model.UserBikeDetailRequest) (*model.UserBikeDetailResponse, error) {
	var (
		err error
		out = &model.UserBikeDetailResponse{}
	)

	userId, _ := auth.ContextUserID(ctx)

	var eg errgroup.Group
	var bikeInfo *entity.Ebike
	eg.Go(func() error {
		bikeInfo, err = postgres.Ebike.Find(ctx, in.EbikeId)
		if err != nil {
			return err
		}

		return nil
	})

	// 用户车辆信息
	var userBikeInfo *entity.UserEbike
	eg.Go(func() error {
		userBikeInfo, _ = a.iUserEbike.FindByParameter(ctx, &model.UserEbikeRequest{
			UserID:  &userId,
			EbikeID: &in.EbikeId,
		})
		return nil
	})

	// 自定义车辆信息
	var userbikeSettingEty *entity.UserBikeSetting
	eg.Go(func() error {
		userbikeSettingEty, _ = postgres.UserBikeSetting.Find(ctx, &model.UserBikeSettingInfoRequest{
			//UserId:  &userId,
			EbikeId: &in.EbikeId,
		})
		return nil
	})

	err = eg.Wait()
	if err != nil {
		return nil, err
	}

	// 车辆名称
	bikeName := bikeInfo.Name
	if userbikeSettingEty.EbikeName != "" {
		bikeName = userbikeSettingEty.EbikeName
	}

	// 车辆图片
	bikeImage := EbikeType.GetBikeImage(bikeInfo.TypeID, bikeInfo.Color)
	/*if userbikeSettingEty.EbikeImage != "" {
		bikeImage = userbikeSettingEty.EbikeImage
	}*/

	out = &model.UserBikeDetailResponse{
		Name:      bikeName,
		Photo:     bikeImage,
		IsManager: userBikeInfo.IsManager,
	}
	return out, err
}

// IsUserBindBike 用户车辆是否绑定
func (a *userEbike) IsUserBindBike(userId, bikeId int64) bool {
	info, err := a.iUserEbike.FindByParameter(context.Background(), &model.UserEbikeRequest{
		UserID:  &userId,
		EbikeID: &bikeId,
	})

	if err != nil || info == nil {
		return false
	}

	return true
}

// IsManager 是否为车主
func (a *userEbike) IsManager(userId, ebikeId int64) bool {
	info, err := a.iUserEbike.FindByParameter(context.Background(), &model.UserEbikeRequest{
		UserID:  &userId,
		EbikeID: &ebikeId,
	})

	if err != nil {
		return false
	}

	return info.IsManager > 0
}

// GetManagerBikeIds 获取车主的车辆ID
func (a *userEbike) GetManagerBikeIds(userId int64) (bikeIds []int64) {
	isManager := 1
	_, list, _ := a.iUserEbike.List(context.Background(), &model.UserEbikeListRequest{
		UserID:    &userId,
		IsManager: &isManager,
	})

	for i := 0; i < len(list); i++ {
		bikeIds = append(bikeIds, list[i].EbikeID)
	}
	return
}

// BatchGetBikeCustomData 批量获取自定义信息
func (a *userEbike) BatchGetBikeCustomData(userId int64, bikeIds []int64) (rets map[int64]*model.CustomUserEbikeInfo) {
	rets = make(map[int64]*model.CustomUserEbikeInfo)
	if len(bikeIds) == 0 {
		return
	}

	// 自定义车辆信息
	_, userbikeSettingEtys, _ := postgres.UserBikeSetting.List(context.Background(), &model.UserBikeSettingListRequest{
		UserId:  &userId,
		BikeIds: bikeIds,
	})

	// 自定义数据
	userBikeSettingMap := make(map[int64]*entity.UserBikeSetting)
	for i := 0; i < len(userbikeSettingEtys); i++ {
		userBikeSettingMap[userbikeSettingEtys[i].EbikeId] = userbikeSettingEtys[i]
	}

	// 车辆信息
	_, bikeList, _ := postgres.Ebike.List(context.Background(), &model.EbikeListRequest{
		BikeIds: bikeIds,
	})

	for i := 0; i < len(bikeList); i++ {
		rets[bikeList[i].ID] = &model.CustomUserEbikeInfo{
			BikeId: bikeList[i].ID,
			Name:   bikeList[i].Name,
			Image:  bikeList[i].Photo,
		}

		// 构建自定义车辆名称和图片
		if v, ok := userBikeSettingMap[bikeList[i].ID]; ok {
			if v != nil {
				rets[bikeList[i].ID].Name = v.EbikeName
				rets[bikeList[i].ID].Image = v.EbikeImage
			}
		}
	}
	return
}

// GetBikeCustomData 获取车辆自定义信息
func (a *userEbike) GetBikeCustomData(userId, bikeId int64) (ret *model.CustomUserEbikeInfo) {
	ret = &model.CustomUserEbikeInfo{
		BikeId: bikeId,
	}
	// 自定义车辆信息
	userbikeSettingEty, _ := postgres.UserBikeSetting.Find(context.Background(), &model.UserBikeSettingInfoRequest{
		//UserId:  &userId,
		EbikeId: &bikeId,
	})

	// 车辆信息
	bikeInfo, err := postgres.Ebike.Find(context.Background(), bikeId)
	if err != nil {
		return
	}

	// 车辆名称
	ret.Name = bikeInfo.Name
	if userbikeSettingEty.EbikeName != "" {
		ret.Name = userbikeSettingEty.EbikeName
	}

	// 车辆图片
	ret.Image = EbikeType.GetBikeImage(bikeInfo.TypeID, bikeInfo.Color)
	/*	if userbikeSettingEty.EbikeImage != "" {
		ret.Image = userbikeSettingEty.EbikeImage
	}*/

	return
}

// GetManagerByBikeId 获取车主
func (a *userEbike) GetManagerByBikeId(bikeId int64) int64 {
	isManager := 1
	info, err := a.iUserEbike.FindByParameter(context.Background(), &model.UserEbikeRequest{
		IsManager: &isManager,
		EbikeID:   &bikeId,
	})

	if err != nil {
		log.Errorf("GetManagerByBikeId failed bikeId:%v", bikeId)
		return 0
	}

	return info.UserID
}

func (a *userEbike) List(ctx context.Context, in *model.UserEbikeListRequest) (*model.UserEbikeListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.UserEbike
		out   = &model.UserEbikeListResponse{}
	)

	if total, list, err = a.iUserEbike.List(ctx, in); err != nil {
		return nil, err
	}

	out.Total = total
	out.Data = model.UserEbikesEntityToDto(list)

	return out, nil
}

func buildUserEbike(in *model.UserEbikeCreateRequest) *entity.UserEbike {
	// todo: check the entity is required
	return &entity.UserEbike{

		UserID: in.UserID,

		EbikeID: in.EbikeID,

		ShareTime: in.ShareTime,

		IsManager: in.IsManager,

		Photo: "",

		CreatedAt: time.Now().Unix(),

		UpdatedAt: time.Now().Unix(),
	}
}
